% PostScript routines test utils.
% Tests should look like this:
%
%     (tag): ... :: ... TEST
%             ^      ^-- stack state after running the code
%             +- code to run, typically a function call
%
% The results are compared using deepeq below, which is better
% than eq but still leaves out a lot.
%
% The expected results are assumed to not contain raw marks,
% because :: is a mark and TEST uses counttomark.
%
% TEST does not show what exactly went wrong.
% Place "stack" before :: and check the output instead.

/TTAG (--) def

/: { /TTAG exch def } def
/:: { mark } def

/EQ <<
	/arraytype { arrayeq }
	/dicttype { dicteq }
>> def

/deepeq { {
	1 index type 1 index type ne { pop pop false exit } if
	dup type EQ exch .knownget { exec } { eq } ifelse exit
} loop } def

/arrayeq {
	1 index length 1 index length eq not {
		pop pop false
	} {
		true 1 index length 1 sub 0 exch 1 exch {	% A B T i
			3 index 1 index get
			3 index 2 index get
			deepeq { pop } { pop pop false exit } ifelse
		} for exch pop exch pop
	} ifelse	
} def

/dicteq {
	dup 2 index dictsemieq
	3 1 roll dictsemieq and
} def

% dict dict -> TF
/dictsemieq {
	true exch {		% dict T k v
		3 index 2 index .knownget {
			deepeq { pop } { pop pop false exit } ifelse
		} {
			pop pop pop false exit
		} ifelse
	} forall exch pop
} def

/TEST { {
	counttomark array astore exch pop
	count 1 roll
	count 1 sub array astore exch		% [ACTUAL] [TEST]

	1 index length 1 index length eq not {
		(FAIL )print TTAG print ( length mismatch\n) print
		exit
	} if
	
	true
	1 index length 1 sub 0 exch 1 exch {		% [A] [T] T i
		3 index 1 index get			% [A] [T] T i Ai
		3 index 2 index get			% [A] [T] T i Ai Ti
		deepeq { pop } { exch pop false exit } ifelse
	} for { (OK ) } { (FAIL ) } ifelse
	print TTAG print (\n) print exit

} loop clear } def
